package com.intgrt.manager.util;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;

public class HttpTools {
	
   public static String getPattern(String content,String pattern){
    	String temp="";
		Pattern r = Pattern.compile(pattern,0x20);
		Matcher m = r.matcher(content);
		if (m.find( )) {
			temp=m.group(1);
		}
		return temp;
    }
	
	public static String getUrlContent(String urlStr, String encoder) throws IOException{
		StringBuffer sb = new StringBuffer();
		String fileLine = "";

		URL url = new URL(urlStr);
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");

		BufferedReader br = null;
		String compress = conn.getContentEncoding();
		if (compress == null)
			compress = "";
		if (compress.equals("gzip")){
			br = new BufferedReader(new InputStreamReader(new GZIPInputStream(conn.getInputStream()), encoder));
		}else{
			br = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoder));
		}
		while ((fileLine = br.readLine()) != null){
			sb.append(fileLine);
			sb.append("\r\n");
		}
		br.close();
		return sb.toString();
	}
	
	public static String getContentByPost(String urlStr, String param, String encode, String cookie) throws IOException {
		URL url = new URL(urlStr);
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setDoOutput(true);
		conn.setDoInput(true);
		conn.setRequestMethod("POST");
		conn.setUseCaches(false);
		conn.setInstanceFollowRedirects(true);
		if (ProjectTools.isNotEmpty(cookie))
			conn.setRequestProperty("Cookie", cookie);
		conn.connect();
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.write(param.getBytes());
		out.flush();
		out.close();
		BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), encode));
		StringBuilder tempStr = new StringBuilder();
		String fileLine = "";
		while ((fileLine = br.readLine()) != null){
			tempStr.append(fileLine);
			tempStr.append("\r\n");
		}
		br.close();
		conn.disconnect();
		return new String(tempStr);
	}
	
	public static String getDomainName(String theLink) {
		if (theLink.substring(7, theLink.length()).indexOf("/") > -1) {
			return theLink.substring(0, theLink.substring(7, theLink.length()).indexOf("/") + 7);
		}
		return theLink;
	}
	
	public static String getHostName(String theLink) {
		String hostname = getDomainName(theLink);
		return hostname.substring(hostname.indexOf("//") + 2, hostname.length());
	}
	
	public static String getContentBySocket(String urlLink, String encode) {
		StringBuffer sb = new StringBuffer();
		String hostname = getHostName(urlLink);
		try {
			Socket socket = new Socket();
			SocketAddress host = new InetSocketAddress(InetAddress.getByName(hostname), 80);
			socket.connect(host, 30000);
			socket.setSoTimeout(30000);

			byte[] bytes =("GET " + urlLink + " HTTP/1.1\r\n" + "Host:" + hostname + "\r\n" + "Accept:*/*\r\n" 
					+ "Accept-Language:zh-cn\r\n" + "Accept-Encoding:gzip,deflate\r\n" 
					+ "User-agent:Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\r\n" 
					+ "Connection:Keep-Alive\r\n" + "\r\n").getBytes(encode);
			socket.getOutputStream().write(bytes);
			socket.shutdownOutput();

			BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream(), encode));
			String line = "";
			while ((line = rd.readLine()) != null) {
				sb.append(line);
				sb.append("\r\n");
			}
			rd.close();
			socket.close();
		} catch (IOException e){
			e.printStackTrace();
		}
		return sb.toString();
	}
	
	/**
     * Send SSL Request（HTTPClient）
     * @return
     */
    public static String sendHTTPRequest(URL url, Object dataBody, String method) {
        String body = null;
        if (dataBody != null) {
            body = JSON.toJSONString(dataBody);
        }
        CloseableHttpClient httpClient = getClient(true);
        String responseContent = null;
        try {
            HttpResponse response = null;
            if (method.equals("POST")) {
                HttpPost httpPost = new HttpPost(url.toURI());
                if (!ProjectTools.isEmpty(body)) {
                    httpPost.setEntity(new StringEntity(body, "UTF-8"));
                }
                response = httpClient.execute(httpPost);
            } else if (method.equals("PUT")) {
                HttpPut httpPut = new HttpPut(url.toURI());
                if (!ProjectTools.isEmpty(body)) {
                    httpPut.setEntity(new StringEntity(body, "UTF-8"));
                }
                response = httpClient.execute(httpPut);
            } else if (method.equals("GET")) {
                HttpGet httpGet = new HttpGet(url.toURI());
                response = httpClient.execute(httpGet);
            } else if (method.equals("DELETE")) {
                HttpDelete httpDelete = new HttpDelete(url.toURI());
                response = httpClient.execute(httpDelete);
            }
            HttpEntity entity = response.getEntity();
            if (null != entity) {
                responseContent = EntityUtils.toString(entity, "UTF-8");
                EntityUtils.consume(entity);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContent;
    }
    
    /**
     * Create a httpClient instance
     * @param isSSL
     * @return HttpClient instance
     */
    private static CloseableHttpClient getClient(boolean isSSL) {
        CloseableHttpClient httpClient = null;
        if (isSSL) {
            X509TrustManager xtm = new X509TrustManager() {
                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };
            try {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[]{xtm}, null);
                SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(ctx);
                httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
        return httpClient;
    }
    
}
